package com.ipan.jfinal.render;

import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;

import com.jfinal.render.Render;
import com.jfinal.render.RenderException;
import com.jfinal.render.RenderManager;

/**
 * 文本内容以文件方式渲染
 * 
 * @author iPan
 * @date 2022-05-17
 */
public class MyTextFileRender extends Render {
	protected static final String DEFAULT_CONTENT_TYPE = "text/plain";
//	protected static ServletContext servletContext;
	
	protected String text = null;
	protected String downloadFileName = null;
	protected String contentType = null;
	protected String encode = "utf-8";

	public MyTextFileRender(String text, String downloadFileName, String contentType, String encode) {
		this.text = text;
		this.downloadFileName = downloadFileName;
		this.contentType = contentType;
		this.encode = (StringUtils.isNoneBlank(encode) ? encode : getEncoding());
	}
	public MyTextFileRender(String text, String downloadFileName) {
		this.text = text;
		this.downloadFileName = downloadFileName;
	}
	
	private String getContentType() {
		return StringUtils.isNotBlank(contentType) ? contentType : DEFAULT_CONTENT_TYPE;
	}
	private String getEncode() {
		return StringUtils.isNotBlank(encode) ? encode : "utf-8";
	}
	private String getFullContentType() {
		return getContentType() + ";charset=" + getEncode();
	}

	@Override
	public void render() {
//		if (StringUtils.isBlank(text)) {
		if (text == null) { // 允许空字符串的文件下载
			RenderManager.me().getRenderFactory().getErrorRender(404).setContext(request, response).render();
			return ;
		}
		
//		response.setHeader("Accept-Ranges", "bytes");
		response.setHeader("Content-Disposition", "attachment; " + encodeFileName(request, downloadFileName));
//		if (StringUtils.isBlank(contentType)) {
//			contentType = servletContext.getMimeType(downloadFileName);
//		}
		response.setContentType(getFullContentType());
		normalRender();
	}
	
	protected void normalRender() {
//		response.setHeader("Content-Length", String.valueOf(text.length()));
		String encode = getEncode();
		PrintWriter writer = null;
		try {
			response.setCharacterEncoding(encode);	// 与 contentType 分开设置
			writer = response.getWriter();
			writer.write(text);
			writer.flush();
		} catch (Exception e) {
			throw new RenderException(e);
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (Exception e) {
				}
			}
		}
	}
	
	/**
	 * 依据浏览器判断编码规则
	 */
	public String encodeFileName(HttpServletRequest request, String fileName) {
		String userAgent = request.getHeader("User-Agent");
		try {
			String encodedFileName = URLEncoder.encode(fileName, "UTF8");
			// 如果没有UA，则默认使用IE的方式进行编码
			if (userAgent == null) {
				return "filename=\"" + encodedFileName + "\"";
			}
			
			userAgent = userAgent.toLowerCase();
			// IE浏览器，只能采用URLEncoder编码
			if (userAgent.indexOf("msie") != -1) {
				return "filename=\"" + encodedFileName + "\"";
			}
			
			// Opera浏览器只能采用filename*
			if (userAgent.indexOf("opera") != -1) {
				return "filename*=UTF-8''" + encodedFileName;
			}
			
			// Safari浏览器，只能采用ISO编码的中文输出,Chrome浏览器，只能采用MimeUtility编码或ISO编码的中文输出
			if (userAgent.indexOf("safari") != -1 || userAgent.indexOf("applewebkit") != -1 || userAgent.indexOf("chrome") != -1) {
				return "filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\"";
			}
			
			// FireFox浏览器，可以使用MimeUtility或filename*或ISO编码的中文输出
			if (userAgent.indexOf("mozilla") != -1) {
				return "filename*=UTF-8''" + encodedFileName;
			}
			
			return "filename=\"" + encodedFileName + "\"";
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
	}
	
}
